home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / lib / ruby / 1.8 / irb.rb < prev    next >
Encoding:
Ruby Source  |  2009-08-09  |  7.4 KB  |  355 lines

  1. #
  2. #   irb.rb - irb main module
  3. #       $Release Version: 0.9.5 $
  4. #       $Revision: 24483 $
  5. #       $Date: 2009-08-09 17:44:15 +0900 (Sun, 09 Aug 2009) $
  6. #       by Keiju ISHITSUKA(keiju@ruby-lang.org)
  7. #
  8. # --
  9. #
  10. #
  11. #
  12. require "e2mmap"
  13.  
  14. require "irb/init"
  15. require "irb/context"
  16. require "irb/extend-command"
  17. #require "irb/workspace"
  18.  
  19. require "irb/ruby-lex"
  20. require "irb/input-method"
  21. require "irb/locale"
  22.  
  23. STDOUT.sync = true
  24.  
  25. module IRB
  26.   @RCS_ID='-$Id: irb.rb 24483 2009-08-09 08:44:15Z shyouhei $-'
  27.  
  28.   class Abort < Exception;end
  29.  
  30.   #
  31.   @CONF = {}
  32.  
  33.   def IRB.conf
  34.     @CONF
  35.   end
  36.  
  37.   # IRB version method
  38.   def IRB.version
  39.     if v = @CONF[:VERSION] then return v end
  40.  
  41.     require "irb/version"
  42.     rv = @RELEASE_VERSION.sub(/\.0/, "")
  43.     @CONF[:VERSION] = format("irb %s(%s)", rv, @LAST_UPDATE_DATE)
  44.   end
  45.  
  46.   def IRB.CurrentContext
  47.     IRB.conf[:MAIN_CONTEXT]
  48.   end
  49.  
  50.   # initialize IRB and start TOP_LEVEL irb
  51.   def IRB.start(ap_path = nil)
  52.     $0 = File::basename(ap_path, ".rb") if ap_path
  53.  
  54.     IRB.setup(ap_path)
  55.  
  56.     if @CONF[:SCRIPT]
  57.       irb = Irb.new(nil, @CONF[:SCRIPT])
  58.     else
  59.       irb = Irb.new
  60.     end
  61.  
  62.     @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
  63.     @CONF[:MAIN_CONTEXT] = irb.context
  64.  
  65.     trap("SIGINT") do
  66.       irb.signal_handle
  67.     end
  68.  
  69.     begin
  70.       catch(:IRB_EXIT) do
  71.     irb.eval_input
  72.       end
  73.     ensure
  74.       irb_at_exit
  75.     end
  76. #    print "\n"
  77.   end
  78.  
  79.   def IRB.irb_at_exit
  80.     @CONF[:AT_EXIT].each{|hook| hook.call}
  81.   end
  82.  
  83.   def IRB.irb_exit(irb, ret)
  84.     throw :IRB_EXIT, ret
  85.   end
  86.  
  87.   def IRB.irb_abort(irb, exception = Abort)
  88.     if defined? Thread
  89.       irb.context.thread.raise exception, "abort then interrupt!!"
  90.     else
  91.       raise exception, "abort then interrupt!!"
  92.     end
  93.   end
  94.  
  95.   #
  96.   # irb interpriter main routine 
  97.   #
  98.   class Irb
  99.     def initialize(workspace = nil, input_method = nil, output_method = nil)
  100.       @context = Context.new(self, workspace, input_method, output_method)
  101.       @context.main.extend ExtendCommandBundle
  102.       @signal_status = :IN_IRB
  103.  
  104.       @scanner = RubyLex.new
  105.       @scanner.exception_on_syntax_error = false
  106.     end
  107.     attr_reader :context
  108.     attr_accessor :scanner
  109.  
  110.     def eval_input
  111.       @scanner.set_prompt do
  112.     |ltype, indent, continue, line_no|
  113.     if ltype
  114.       f = @context.prompt_s
  115.     elsif continue
  116.       f = @context.prompt_c
  117.     elsif indent > 0
  118.       f = @context.prompt_n
  119.     else @context.prompt_i
  120.       f = @context.prompt_i
  121.     end
  122.     f = "" unless f
  123.     if @context.prompting?
  124.       @context.io.prompt = p = prompt(f, ltype, indent, line_no)
  125.     else
  126.       @context.io.prompt = p = ""
  127.     end
  128.     if @context.auto_indent_mode
  129.       unless ltype
  130.             ind = prompt(@context.prompt_i, ltype, indent, line_no)[/.*\z/].size +
  131.           indent * 2 - p.size
  132.         ind += 2 if continue
  133.         @context.io.prompt = p + " " * ind if ind > 0
  134.       end
  135.     end
  136.       end
  137.        
  138.       @scanner.set_input(@context.io) do
  139.     signal_status(:IN_INPUT) do
  140.       if l = @context.io.gets
  141.         print l if @context.verbose?
  142.       else
  143.         if @context.ignore_eof? and @context.io.readable_atfer_eof?
  144.           l = "\n"
  145.           if @context.verbose?
  146.         printf "Use \"exit\" to leave %s\n", @context.ap_name
  147.           end
  148.         end
  149.       end
  150.       l
  151.     end
  152.       end
  153.  
  154.       @scanner.each_top_level_statement do |line, line_no|
  155.     signal_status(:IN_EVAL) do
  156.       begin
  157.             line.untaint
  158.         @context.evaluate(line, line_no)
  159.         output_value if @context.echo?
  160.         exc = nil
  161.       rescue Interrupt => exc
  162.       rescue SystemExit, SignalException
  163.         raise
  164.       rescue Exception => exc
  165.       end
  166.       if exc
  167.         print exc.class, ": ", exc, "\n"
  168.         if exc.backtrace[0] =~ /irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/
  169.           irb_bug = true 
  170.         else
  171.           irb_bug = false
  172.         end
  173.         
  174.         messages = []
  175.         lasts = []
  176.         levels = 0
  177.         for m in exc.backtrace
  178.           m = @context.workspace.filter_backtrace(m) unless irb_bug
  179.           if m
  180.         if messages.size < @context.back_trace_limit
  181.           messages.push "\tfrom "+m
  182.         else
  183.           lasts.push "\tfrom "+m
  184.           if lasts.size > @context.back_trace_limit
  185.             lasts.shift 
  186.             levels += 1
  187.           end
  188.         end
  189.           end
  190.         end
  191.         print messages.join("\n"), "\n"
  192.         unless lasts.empty?
  193.           printf "... %d levels...\n", levels if levels > 0
  194.           print lasts.join("\n")
  195.         end
  196.         print "Maybe IRB bug!!\n" if irb_bug
  197.       end
  198.           if $SAFE > 2
  199.             abort "Error: irb does not work for $SAFE level higher than 2"
  200.           end
  201.     end
  202.       end
  203.     end
  204.  
  205.     def suspend_name(path = nil, name = nil)
  206.       @context.irb_path, back_path = path, @context.irb_path if path
  207.       @context.irb_name, back_name = name, @context.irb_name if name
  208.       begin
  209.     yield back_path, back_name
  210.       ensure
  211.     @context.irb_path = back_path if path
  212.     @context.irb_name = back_name if name
  213.       end
  214.     end
  215.  
  216.     def suspend_workspace(workspace)
  217.       @context.workspace, back_workspace = workspace, @context.workspace
  218.       begin
  219.     yield back_workspace
  220.       ensure
  221.     @context.workspace = back_workspace
  222.       end
  223.     end
  224.  
  225.     def suspend_input_method(input_method)
  226.       back_io = @context.io
  227.       @context.instance_eval{@io = input_method}
  228.       begin
  229.     yield back_io
  230.       ensure
  231.     @context.instance_eval{@io = back_io}
  232.       end
  233.     end
  234.  
  235.     def suspend_context(context)
  236.       @context, back_context = context, @context
  237.       begin
  238.     yield back_context
  239.       ensure
  240.     @context = back_context
  241.       end
  242.     end
  243.  
  244.     def signal_handle
  245.       unless @context.ignore_sigint?
  246.     print "\nabort!!\n" if @context.verbose?
  247.     exit
  248.       end
  249.  
  250.       case @signal_status
  251.       when :IN_INPUT
  252.     print "^C\n"
  253.     raise RubyLex::TerminateLineInput
  254.       when :IN_EVAL
  255.     IRB.irb_abort(self)
  256.       when :IN_LOAD
  257.     IRB.irb_abort(self, LoadAbort)
  258.       when :IN_IRB
  259.     # ignore
  260.       else
  261.     # ignore other cases as well
  262.       end
  263.     end
  264.  
  265.     def signal_status(status)
  266.       return yield if @signal_status == :IN_LOAD
  267.  
  268.       signal_status_back = @signal_status
  269.       @signal_status = status
  270.       begin
  271.     yield
  272.       ensure
  273.     @signal_status = signal_status_back
  274.       end
  275.     end
  276.  
  277.     def prompt(prompt, ltype, indent, line_no)
  278.       p = prompt.dup
  279.       p.gsub!(/%([0-9]+)?([a-zA-Z])/) do
  280.     case $2
  281.     when "N"
  282.       @context.irb_name
  283.     when "m"
  284.       @context.main.to_s
  285.     when "M"
  286.       @context.main.inspect
  287.     when "l"
  288.       ltype
  289.     when "i"
  290.       if $1 
  291.         format("%" + $1 + "d", indent)
  292.       else
  293.         indent.to_s
  294.       end
  295.     when "n"
  296.       if $1 
  297.         format("%" + $1 + "d", line_no)
  298.       else
  299.         line_no.to_s
  300.       end
  301.     when "%"
  302.       "%"
  303.     end
  304.       end
  305.       p
  306.     end
  307.  
  308.     def output_value
  309.       if @context.inspect?
  310.         printf @context.return_format, @context.last_value.inspect
  311.       else
  312.         printf @context.return_format, @context.last_value
  313.       end
  314.     end
  315.  
  316.     def inspect
  317.       ary = []
  318.       for iv in instance_variables
  319.     case iv
  320.     when "@signal_status"
  321.       ary.push format("%s=:%s", iv, @signal_status.id2name)
  322.     when "@context"
  323.       ary.push format("%s=%s", iv, eval(iv).__to_s__)
  324.     else
  325.       ary.push format("%s=%s", iv, eval(iv))
  326.     end
  327.       end
  328.       format("#<%s: %s>", self.class, ary.join(", "))
  329.     end
  330.   end
  331.  
  332.   # Singleton method
  333.   def @CONF.inspect
  334.     IRB.version unless self[:VERSION]
  335.  
  336.     array = []
  337.     for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name}
  338.       case k
  339.       when :MAIN_CONTEXT, :__TMP__EHV__
  340.     array.push format("CONF[:%s]=...myself...", k.id2name)
  341.       when :PROMPT
  342.     s = v.collect{
  343.       |kk, vv|
  344.       ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"}
  345.       format(":%s=>{%s}", kk.id2name, ss.join(", "))
  346.     }
  347.     array.push format("CONF[:%s]={%s}", k.id2name, s.join(", "))
  348.       else
  349.     array.push format("CONF[:%s]=%s", k.id2name, v.inspect)
  350.       end
  351.     end
  352.     array.join("\n")
  353.   end
  354. end
  355.